package com.enzoism.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MainClient {
    public static void main(String[] args) {

        // 保存编译的文件
        System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

        // 动态代理学习-1[直接替换]
//        dynamicProxy1();

        // 动态代理学习-2[让类实现InvocationHandler]
//        dynamicProxy2();
//        dynamicProxy3();

        // 动态代理学习-4[让类实现InvocationHandler-将代理处理逻辑全部拆出去]
//        dynamicProxy4();

        // 动态代理学习-5[让类实现InvocationHandler-将代理处理逻辑全部拆出去-直接传递接口]
        // 因为没有用到真实的实现类，所以在代理中，我们要判断用户的真实参数和方法名，在里面做通用逻辑判断
        dynamicProxy5();
        dynamicProxy6();

    }

    public static void dynamicProxy1() {
        SingerService singerService = new SingerServiceImpl("周杰伦");

        // 使用反射直接生成当前的接口代理
        SingerService agent = (SingerService) Proxy.newProxyInstance(MainClient.class.getClassLoader(), singerService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("我是代理，谈合作，拉投资，布置场地");
                // 要调用的那个类[接口]的哪个方法，传入哪些值
                Object invoke = method.invoke(singerService, args);
                System.out.println("我是代理，项目结算");
                System.out.println();
                return invoke;
            }
        });
        agent.sing();
    }

    public static void dynamicProxy2() {
        SingerService singerService = new SingerServiceImpl("周杰伦");

        // 使用反射直接生成当前的接口代理
        SingerService agent = (SingerService) Proxy.newProxyInstance(MainClient.class.getClassLoader(), singerService.getClass().getInterfaces(), new Agent(singerService));
        agent.sing();
    }

    public static void dynamicProxy3() {
        SqlService service = new SqlServiceImp();

        // 使用反射直接生成当前的接口代理
        SqlService agent = (SqlService) Proxy.newProxyInstance(MainClient.class.getClassLoader(), service.getClass().getInterfaces(), new Agent(service));
        agent.saveName("小明");
    }

    public static void dynamicProxy4() {
        SqlService service = new SqlServiceImp();
        // 使用反射直接生成当前的接口代理
        SqlService agent = (SqlService) Agent.getProxy(service);
        agent.saveName("小明");
    }

    public static void dynamicProxy5() {
        // 使用反射直接生成当前的接口代理
        SqlService agent = Agent2.getProxy(SqlService.class);
        agent.saveName("小明");
    }
    public static void dynamicProxy6() {
        // 使用反射直接生成当前的接口代理
        SingerService agent = Agent2.getProxy(SingerService.class);
        agent.sing();
    }
}
